package com.xquant.marketdata.curvestrip.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.github.pagehelper.PageInfo;
import com.xquant.common.security.utils.SecurityUtils;
import com.xquant.marketdata.curvestrip.domain.IrCurveSetDTO;
import com.xquant.marketdata.curvestrip.domain.IrCurveStripDTO;
import com.xquant.marketdata.curvestrip.entity.IrCurveDTO;
import com.xquant.marketdata.curvestrip.mapper.IrCurveStripMapper;
import com.xquant.marketdata.curvestrip.service.IrCurveStripService;
import com.xquant.marketdata.utils.SortUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @Auther: B946
 * @Date: 23/04/2020 11:26
 * @Description:
 */
@Service(IrCurveStripService.BEAN_NAME)
public class IrCurveStripServiceImpl implements IrCurveStripService {

    @Autowired
    private IrCurveStripMapper irCurveStripMapper;

    private Map<String, IrCurveStripService> map = new HashMap<>();

    @Override
    public List<IrCurveSetDTO> queryIrCurveByPage(Map params) {
        List<IrCurveSetDTO> list = irCurveStripMapper.queryIrCurveByPage(params);
//        list.stream().forEach(IrCurveSetDTO -> {
//            if (!StrUtil.isNotBlank(IrCurveSetDTO.getuAType())) {
//                IrCurveSetDTO.setuAType("*");
//            }
//            if (!StrUtil.isNotBlank(IrCurveSetDTO.getuMType())) {
//                IrCurveSetDTO.setuMType("*");
//            }
//        });
        return list;
    }

    @Override
    public List<IrCurveSetDTO> queryTirCurveCombox(Map<String, Object> params) {
        List<IrCurveSetDTO> list = irCurveStripMapper.queryIrCurveCombox(params);
        return list;
    }

    @Override
    public PageInfo<Map> queryIrCurveRefSetByPage(Map params) {
        List list = irCurveStripMapper.queryIrCurveRefSetByPage(params);
        return new PageInfo<>(list);
    }

    @Override
    public List<IrCurveStripDTO> queryIrCurveRatesByPage(Map params) {
        List<Map> list = irCurveStripMapper.queryIrCurveRatesByPage(params);
        List<Map> maps = SortUtil.sortTerm(list, "irc_term", true);
        ArrayList<IrCurveStripDTO> resultList = new ArrayList<>();
        for (Map res : maps) {
            IrCurveStripDTO irCurveStripDTO = BeanUtil.fillBeanWithMap(res, new IrCurveStripDTO(), false);
            resultList.add(irCurveStripDTO);
        }
//        List<IrCurveStripDTO> resultList = maps.stream().map(m -> BeanUtil.fillBeanWithMap(map, new IrCurveStripDTO(), false)).collect(Collectors.toList());
        return resultList;
    }

    @Override
    public List<Map> getIrCurveMx(Map params) {
        List list = irCurveStripMapper.queryIrCurveByPage(params);
        return list;
    }

    @Override
    public void updateIrCurve(Map params) {
        irCurveStripMapper.updateIrCurve(params);
    }

    @Override
    public void insertIrCurve(Map params) {

        irCurveStripMapper.insertIrCurve(params);
    }

    @Override
    @Transactional
    public void deleteIrCurve(Map params) {
        irCurveStripMapper.deleteIrCurve(params);
        irCurveStripMapper.deleteAllIrcCurveRates(params);
        //删除用户和部门权限表数据
        removeUserPermCurve(params);
        removeDeptPermCurve(params);
        //删除读写权限表数据
        removeUserCurveByIrcCode(params);
        removeDeptCurveByIrcCode(params);
    }

    @Override
    public void updateIrCurveRefSet(Map params) {
        irCurveStripMapper.updateIrCurveRefSet(params);
    }

    @Override
    public void updateIrCurveRates(Map params) {
        irCurveStripMapper.updateIrCurveRates(params);
    }

    @Override
    public void insertIrCurveRefSetByDate(Map params) {
        irCurveStripMapper.insertIrCurveRefSetByDate(params);
    }

    @Override
    public void insertIrCurveRefSet(Map params) {
        irCurveStripMapper.insertIrCurveRefSet(params);
    }

    @Override
    public void insertIrCurveRates(Map params) {
        irCurveStripMapper.insertIrCurveRates(params);
    }

    @Override
    public void deleteIrCurveRefSet(Map params) {
        irCurveStripMapper.deleteIrCurveRefSet(params);
    }

    @Override
    public void deleteIrCurveRates(Map params) {
        irCurveStripMapper.deleteIrCurveRates(params);
    }

    @Override
    public void deleteIrCurveRefSetByDate(Map params) {
        irCurveStripMapper.deleteIrCurveRefSetByDate(params);
    }

    @Override
    public void deleteAllIrCurveRefSet(Map params) {
        irCurveStripMapper.deleteAllIrCurveRefSet(params);
    }

    @Override
    public void filterIrCurveRefSet(Map params) {
        irCurveStripMapper.filterIrCurveRefSet(params);
    }

    @Override
    public PageInfo queryFilterIrCurveRefSetByPage(Map params) {
        List list = irCurveStripMapper.queryFilterIrCurveRefSetByPage(params);
        return new PageInfo<>(list);
    }

    @Override
    public void deleteIrCurveList(HashMap<String, Set<String>> map) {
        map.keySet().stream().forEach(vlist->{
            HashMap<String, Object> hashMap = new HashMap<>();
            hashMap.put("irCurve",vlist);
            Set<String> dateList = map.get(vlist);
            hashMap.put("list",dateList);
            irCurveStripMapper.deleteIrCurveList(hashMap);
        });
    }

    @Override
    public List<IrCurveDTO> getLastIrCurve(HashMap<String, Set<String>> map, List<IrCurveDTO> list) {
        map.keySet().stream().forEach(vls->{
            TreeSet<String> set = new TreeSet<>(((o1, o2)->o1.compareTo(o2)));
            set.addAll(map.get(vls));
            // 更新最新的ircCode对应的结束日期改为导入的日期期间中最小的
            HashMap<String, String> hashMap = new HashMap<>();
            hashMap.put("ircCode",vls);
            hashMap.put("begDate",set.first());
            irCurveStripMapper.updateIrCurveByBegDate(hashMap);

            HashMap<String, Object> hashMap2 = new HashMap<>();
            hashMap2.put("ircCode",vls);
            hashMap2.put("endDate",set.last());
            String nextDate = irCurveStripMapper.getNextDay(hashMap2);
            if (nextDate != null) {
                list.stream().filter(data ->
                        data.getIrcCode().equals(vls)&&data.getBegDate().equals(set.last())
                ).forEach(data -> {
                    data.setEndDate(nextDate);
                    data.setImpDate(DateUtil.format(new Date(),"yyyy-MM-dd"));
                    data.setImpTime(DateUtil.now());
                });
            }else{
                list.stream().forEach(data -> {
                    data.setEndDate("2050-12-31");
                    data.setImpDate(DateUtil.format(new Date(),"yyyy-MM-dd"));
                    data.setImpTime(DateUtil.now());
                });
            }

        });
        return list;
    }

    @Override
    public boolean insertIrCurveList(List<IrCurveDTO> list) {
        try{
            int insertLength = list.size();
            int i = 0;
            while (insertLength > 600) {
                irCurveStripMapper.insertIrCurveList(list.subList(i, i + 600));
                i = i + 600;
                insertLength = insertLength - 600;
            }
            if (insertLength > 0) {
                irCurveStripMapper.insertIrCurveList(list.subList(i, i + insertLength));
            }
        }catch (Exception e){
            return false;
        }
        return true;
    }

    @Override
    public boolean insertIrCurve2(IrCurveDTO form) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("ircCode",form.getIrcCode());
        map.put("ircTerm",form.getIrcTerm().toUpperCase(Locale.ROOT));
        map.put("ircRate",form.getIrcRate());
        map.put("begDate",form.getBegDate());
        map.put("endDate",form.getEndDate());
        Map irCurveStrip = irCurveStripMapper.getLastDay(map);
        if (irCurveStrip!=null) {
            irCurveStrip.put("END_DATE",map.get("begDate"));
            irCurveStripMapper.updateIrCurveRatesLastDay(irCurveStrip);
        }
        Map nextOne = irCurveStripMapper.getNextOne(map);
        if (nextOne!=null) {
            map.put("endDate",nextOne.get("BEG_DATE"));
        }
        irCurveStripMapper.deleteIrCurveOne(map);
        irCurveStripMapper.insertIrCurveRates(map);
        return false;
    }

    @Override
    public IrCurveSetDTO getByIrcCode(String ircCode) {
        IrCurveSetDTO irCurveDTO = irCurveStripMapper.getByIrcCode(ircCode);
        return irCurveDTO;
    }

    @Override
    @Transactional
    public void allocateIrCurve(Map<String, Object> param) {
        /*****************************权限部分*****************************************/
        ArrayList<String> userPerms = new ArrayList<>();
        ArrayList<String> deptPerms = new ArrayList<>();
        /** 为读写表赋权*/
        //存放创建人所属部门和上级部门，必须写权限
        ArrayList<String> deptAncestors = new ArrayList<>();
        //存放其他部门
        ArrayList<String> anotherDepts = new ArrayList<>();
        //存放其他人的数组
        ArrayList<String> anotherUser = new ArrayList<>();
        Map<String,Object> deptCfgRights = new HashMap<>();
        Map<String,Object> anotherDeptCfgRights = new HashMap<>();
        String allocateDeptAndUsers = param.get("allocateDeptAndUser").toString();
        String userId = String.valueOf(SecurityUtils.getUserId());
        String ircCode = String.valueOf(param.get("ircCode"));
        String ircRight=String.valueOf(param.get("ircRight"));
        HashMap map= com.alibaba.fastjson2.JSONObject.parseObject( ircRight,HashMap.class);
        //创建人所属部门
        String createDeptId = SecurityUtils.getLoginUser().getSysUser().getDeptId().toString();
        deptAncestors.add(createDeptId);
        //将创建人所属部门的上级部门加入deptPerms
        String deptAncestorIds = irCurveStripMapper.getDeptAncestors(createDeptId);
        List<String> deptAncestorIdArrs = Arrays.asList(deptAncestorIds.split(","));
        for (String deptAncestorArr : deptAncestorIdArrs) {
            if ("0".equals(deptAncestorArr) != true) {
                deptPerms.add(deptAncestorArr);
                deptAncestors.add(deptAncestorArr);
            }
        }
        for (String allocateDeptAndUser : allocateDeptAndUsers.split(",")) {
            if (allocateDeptAndUser.charAt(0) == 'u') {
                userPerms.add(allocateDeptAndUser.substring(2));
                if(!userId.equals(allocateDeptAndUser.substring(2))){
                    //不是本人，赋予传过来的权限
                    anotherUser.add(allocateDeptAndUser.substring(2));
                }
            } else if (allocateDeptAndUser.charAt(0) == 'd') {
                deptPerms.add(allocateDeptAndUser.substring(2));
                if(!createDeptId.equals(allocateDeptAndUser.substring(2))){
                    //不是所属部门，赋予传过来的权限
                    anotherDepts.add(allocateDeptAndUser.substring(2));
                }
            }
        }
        // param中放入用户id和部门id，用于后续的tsys_user_perm和tsys_dept_perm
        if (userPerms.size() > 0) {
            param.put("userIds", userPerms);
        }
        if (deptPerms.size() > 0) {
            param.put("deptIds", deptPerms);
        }
        List<IrCurveSetDTO>  anotherUserList=new ArrayList<>();
        //为创建人单独赋写权限
        IrCurveSetDTO createSet=new IrCurveSetDTO();
        createSet.setCreateBy(userId);
        createSet.setIrcCode(ircCode);
        createSet.setIrcRight("2");
        anotherUserList.add(createSet);
        //其他人传过来的权限
        if(anotherUser.size() != 0){
            for (String authId:anotherUser) {
                IrCurveSetDTO anotherSet=new IrCurveSetDTO();
                anotherSet.setCreateBy(authId);
                anotherSet.setIrcCode(ircCode);
                anotherSet.setIrcRight(map.get(anotherSet.getCreateBy()).toString());
                anotherUserList.add(anotherSet);
            }
            insertUserIrCurveRight(anotherUserList);
        }
        //为所属部门和上级部门单独赋写权限
        deptCfgRights.put("deptIds",deptAncestors);
        deptCfgRights.put("ircCode",ircCode);
        deptCfgRights.put("ircRight","2");
        insertDeptIrCurveRight(deptCfgRights);
        //为其他部门赋传过来的权限
        anotherDepts.removeAll(deptAncestors);
        if(anotherDepts.size() != 0){
            anotherDeptCfgRights.put("deptIds",anotherDepts);
            anotherDeptCfgRights.put("ircCode",ircCode);
            anotherDeptCfgRights.put("ircRight","2");
            insertDeptIrCurveRight(anotherDeptCfgRights);
        }

        /** 更新tsys_usr_perm和tsys_dept_perm **/
        updateCurveUserPerm(param);
        updateCurveDeptPerm(param);
        /*******************************************************************************/
    }

    @Override
    public void updateCurveUserAuthority(Map<String, Object> params) {
        List<Integer> userIds = (List<Integer>) params.get("userIds");
        String ircRight = String.valueOf(params.get("ircRight"));
        String deptId = String.valueOf(params.get("deptId"));
        //存放上级部门
        ArrayList<String> deptAncestors = new ArrayList<>();
        //将创建人所属部门的上级部门加入deptPerms
        String deptAncestorIds = irCurveStripMapper.getDeptAncestors(deptId);
        List<String> deptAncestorIdArrs = Arrays.asList(deptAncestorIds.split(","));
        for (String deptAncestorArr : deptAncestorIdArrs) {
            if ("0".equals(deptAncestorArr) != true) {
                deptAncestors.add(deptAncestorArr);
            }
        }
        for(Integer userId : userIds){
            Map<String,Object> param = new HashMap<>();
            param.put("userId",userId);
            param.put("ircCode",params.get("ircCode"));
            param.put("deptId",deptId);
            param.put("ircRight",ircRight);
            if("1".equals(irCurveStripMapper.queryCurveFlagByUserId(String.valueOf(userId)))){
                //如果tsys_user_flag为1，则改其部门权限
                List<Map> list = irCurveStripMapper.queryCurveDept(param);
                if (list.size() == 0 && !"0".equals(ircRight)) {
                    //如果原来没有权限且需要权限，直接插入
                    irCurveStripMapper.saveCurveDept(param);
                } else if(list.size() != 0 && !"0".equals(ircRight)){
                    //如果原本有权限且不是无权限，则修改
                    irCurveStripMapper.updateCurveDept(param);
                }else if(list.size() != 0 && "0".equals(ircRight)){
                    //如果原本有权限且无权限，直接删除
                    irCurveStripMapper.deleteCurveDept(param);
                }
                //修改对应dept_id的tsys_dept_perm，先清空
                removeDeptPermCurveByDeptId(param);
                if(!"0".equals(ircRight)) {
                    //先给传过来的部门赋权
                    params.put("deptIds",Arrays.asList(deptId));
                    updateCurveDeptPerm(params);
                    //给传过来的部门的上级部门赋值
                    Map<String,Object> deptParams = new HashMap<>();
                    deptParams.put("deptIds",deptAncestors);
                    deptParams.put("ircCode",params.get("ircCode"));
                    deptParams.put("ircRight",2);
                    for(String deId : deptAncestors){
                        deptParams.put("deptId",deId);
                        irCurveStripMapper.deleteCurveDept(deptParams);
                        irCurveStripMapper.saveCurveDept(deptParams);
                        removeDeptPermCurveByDeptId(deptParams);
                    }
                    if(deptAncestors.size()>0){
                        updateCurveDeptPerm(deptParams);
                    }

                }
            }else{
                //flag不为1，则直接修改对应用户
                List<Map> list = irCurveStripMapper.queryCurveUserPerm(param);
                if (list.size() == 0 && !"0".equals(ircRight)) {
                    irCurveStripMapper.saveCurveUser(param);
                } else if(list.size() != 0 && !"0".equals(ircRight)){
                    irCurveStripMapper.updateCurveUser(param);
                }else if(list.size() != 0 && "0".equals(ircRight)){
                    irCurveStripMapper.deleteCurveUser(param);
                }
                removeUserPermCurveByUserId(param);
            }
        }
        if(!"0".equals(ircRight)) {
            updateCurveUserPerm(params);
        }
    }


    @Override
    public int queryIrCurveRefSetByDate(Map params) {
        int ct = irCurveStripMapper.queryIrCurveRefSetByDate(params);
        return ct;
    }

    public void insertUserIrCurveRight(List<IrCurveSetDTO> ircRightlist) {
        irCurveStripMapper.batchInsertCurveUser(ircRightlist);
    }

    public void insertDeptIrCurveRight(Map map) {
        irCurveStripMapper.batchInsertCurveDept(map);
    }

    public void removeUserPermCurveByUserId(Map param) {
        irCurveStripMapper.removeUserPermCurveByUserId(param);
    }

    public void removeDeptPermCurveByDeptId(Map param) {
        irCurveStripMapper.removeDeptPermCurveByDeptId(param);
    }

    public void removeUserPermCurve(Map param) {
        irCurveStripMapper.removeUserPermCurve(param);
    }

    public void removeDeptPermCurve(Map param) {
        irCurveStripMapper.removeDeptPermCurve(param);
    }

    public void removeUserCurveByIrcCode(Map param){
        irCurveStripMapper.removeUserCurveByIrcCode(param);
    }

    public void removeDeptCurveByIrcCode(Map param){
        irCurveStripMapper.removeDeptCurveByIrcCode(param);
    }

    public void updateCurveUserPerm(Map<String, Object> params) {
        irCurveStripMapper.updateUserPermCurve(params);
    }

    public void updateCurveDeptPerm(Map<String, Object> params) {
        irCurveStripMapper.updateDeptPermCurve(params);
    }
    public List<IrCurveSetDTO> checkIrCurve(Map<String, Object> params){
        return irCurveStripMapper.checkIrCurve(params);
    }
}
